using System;
using System.Collections.Generic;
using System.Text;
using MaxFramework;

namespace DuplicateFileFinder
{
    public class Engine
    {

        private System.Threading.Thread mThread = null;
        private bool mInSearching = false;
        private EventManager mEventManager = null;

        public Engine(EventManager pEventManager)
        {
            mEventManager = pEventManager;

            SearchPathList = new List<SearchPath>();
            CompareResultList = new List<ResultFile>();
        }

        public void Save()
        {

            SearchPathList.ToXml().SaveAllText(".\\SearchPathList.xml");
            CompareResultList.ToXml().SaveAllText(".\\CompareResultList.xml");
        }

        public System.Collections.Generic.List<SearchPath> SearchPathList
        {
            get;
            set;
        }

        public bool InSearching
        {
            get
            {
                return mInSearching;
            }
        }

        public System.Collections.Generic.List<ResultFile> CompareResultList
        {
            get;
            set;
        }

        public void StopCompare()
        {
            if (mThread != null)
            {
                if (mThread.ThreadState == System.Threading.ThreadState.WaitSleepJoin ||
                    mThread.ThreadState == System.Threading.ThreadState.Running ||
                    mThread.ThreadState == System.Threading.ThreadState.Background)
                {
                    try
                    {
                        mThread.Abort();
                        mThread = null;
                    }
                    catch { }
                }
            }
        }

        public void StartCompare()
        {
            if (mThread != null)
            {
                if (mThread.ThreadState == System.Threading.ThreadState.WaitSleepJoin ||
                    mThread.ThreadState == System.Threading.ThreadState.Running ||
                    mThread.ThreadState == System.Threading.ThreadState.Background)
                {
                    return;
                }
            }

            mThread = new System.Threading.Thread(new System.Threading.ThreadStart(StartCompareThread));
            mThread.Start();
        }

        public void StartCompareThread()
        {
            mInSearching = true;

            DateTime tStart = DateTime.Now;

            CompareResultList.Clear();

            foreach (SearchPath tSearchPath in SearchPathList)
            {
                string[] tFileList = System.IO.Directory.GetFiles(tSearchPath.Path, tSearchPath.Pattern, tSearchPath.Recursive ? System.IO.SearchOption.AllDirectories : System.IO.SearchOption.TopDirectoryOnly);

                foreach (string tFile in tFileList)
                {
                    if (!CompareResultList.Exists(t => t.FileName.Equals(tFile, StringComparison.CurrentCultureIgnoreCase)))
                    {
                        CompareResultList.Add(new ResultFile(tFile));
                    }
                }
            }

            System.Collections.Hashtable tFoundList = new System.Collections.Hashtable();

            int tCurrent = 0;
            //TimeSpan tEstimated = new TimeSpan();
            foreach (ResultFile tResultFileA in CompareResultList)
            {
                DateTime tCheck = DateTime.Now;
                tCurrent++;



                foreach (ResultFile tResultFileB in CompareResultList)
                {
                    if (!object.ReferenceEquals(tResultFileA, tResultFileB) && !tResultFileB.Compared)
                    {
                        bool tEquals = tResultFileA.Compare(tResultFileB);

                        //////if (tEquals && tResultFileA.Name.Equals(tResultFileB.Name, StringComparison.CurrentCultureIgnoreCase))
                        //////{
                        //////    tResultFileA.MatchByNameList.Add(tResultFileB.FileName, tResultFileB);
                        //////    tResultFileB.MatchByNameList.Add(tResultFileA.FileName, tResultFileA);
                        //////}

                        if (tEquals && !tFoundList.ContainsKey(tResultFileB.FileName))
                        {
                            tFoundList.Add(tResultFileB.FileName, tResultFileB);
                            tResultFileA.BinaryMatchList.Add(tResultFileB);
                            tResultFileB.BinaryMatchList.Add(tResultFileA);
                        }
                    }
                }

                tResultFileA.Compared = true;
                TimeSpan tSingle = DateTime.Now - tCheck;

                TimeSpan tEstimated = new TimeSpan(0, 0, ((CompareResultList.Count - tCurrent) * (int)Math.Round(tSingle.TotalSeconds)));
                mEventManager.UpdateProgress(CompareResultList.Count, tCurrent, "Comparing Estimated (" + tEstimated + ")");
            }

            mInSearching = false;

            TimeSpan tTook = DateTime.Now - tStart;

            mEventManager.UpdateProgress(0, 0, "Took: " + tTook.ToString());//+ ", Estimated: " + tEstimated);

            mEventManager.UpdateViewer();
        }
    }
}
